<template> 
	<view class="date-time">
		<picker-view
			class="picker-view"
			indicator-style="height: 50px;font-size: 38rpx; font-weight: 700; color: #333" 
			:value="value" 
			@change="change">
			<picker-view-column class="picker-view-cloumn">
				<view
					style="line-height: 50px;"
					v-for="item in years" 
					:key="item.number" 
					class="item text-main">
					{{item.text || ''}}
				</view>
			</picker-view-column>
			<picker-view-column class="picker-view-cloumn" v-if="showYear">
				<view 
					style="line-height: 50px;"
					v-for="item in months" 
					:key="item.number"  
					class="item text-main">
					{{item.text || ''}}
				</view>
			</picker-view-column>
			<picker-view-column class="picker-view-cloumn" v-if="showMonth">
				<view 
					style="line-height: 50px;"
					v-for="item in days" 
					:key="item.number"  
					class="item">
					{{item.text || ''}}
				</view>
			</picker-view-column>
			<picker-view-column class="picker-view-cloumn time" v-if="showTime">
				<view 
					style="line-height: 50px;"
					v-for="item in hours" 
					:key="item.number"  
					class="item text-main">
					{{item.text || ''}}
				</view>
			</picker-view-column>
			<picker-view-column class="picker-view-cloumn" v-if="showTime">
				<view 
					style="line-height: 50px;"
					v-for="item in minutes" 
					:key="item.number"  
					class="item text-main">
					{{item.text || ''}}
				</view>
			</picker-view-column>
		</picker-view>
		<view class="d-flex j-sb a-center">
			<button class="cancel-button" :class="theme" @tap="cancel">取消</button>
			<button class="primary-button" :class="theme" @click="confirm">确认</button>
		</view>
	</view>
</template>

<script>
import * as utils from '../utils.js'; // 封装的工具集
export default {
	/**
	 * 数据
	 */
	props: {
		// 是否禁用
		disabled: {
			type: Boolean,
			default: false
		},

		// 占位符
		placeholder: {
			type: String,
			default: '请选择日期时间'
		},

		// 表示有效日期时间范围的开始，
		// 字符串格式为 "YYYY-MM-DD hh:mm"
		start: {
			type: String,
			default: '2022-1-1 00:00'
		},

		// 表示有效日期时间范围的结束
		// 字符串格式为 "YYYY-MM-DD hh:mm"
		end: {
			type: String,
			default: '2300-1-1 00:00'
		},

		// 表示选择器的粒度，有效值：year | month | day | hour | minute
		fields: {
			type: String,
			default: 'minute'
		},

		// 默认值
		// 字符串格式为 "YYYY-MM-DD hh:mm"
		defaultValue: {
			type: String,
			default: ''
		},
		// 只显示年月日
		showTime: {
			type: Boolean,
			default: true
		},
		// 只显示年月
		showMonth: {
			type: Boolean,
			default: true
		},
		// 只显示年
		showYear: {
			type: Boolean,
			default: true
		},
    theme: String
	},

	/**
	 * 数据
	 */
	data() {
		return {
      years: [],
      months: [],
      days: [],
      hours: [],
      minutes: [],
			range: [],
			value: [],
			dateStr: '',            // 最终显示的字符串
			dtStart: null,          // 有效范围开始
			dtEnd: null,            // 有效范围结束
			lastMonthIndex: 0,       // 监听月份改变
			lastYearIndex: 0,

		};
	},
	
	/**
	 * 组件初次加载完成
	 */
	mounted() {
		this.updateValidDate()
		this.initPickerData()
	},

	watch: {
    // 默认值发生变化
		defaultValue() {
			this.updateValidDate()
			this.initPickerData()
    },
    // 起始值发生变化
    startTime() {
      this.updateValidDate()
			this.initPickerData()
    }
	},

	/**
	 * 方法
	 */
	methods: {
		// 更新有效的起始日期
		updateValidDate() {
			// 有效日期开始和结束
			let start = this.start;
			let end = this.end;
			
			// 验证是否是有效的开始和结束日期
			if(!utils.isString(this.start)) {
				start = '2022-1-1 00:00';
			}
			if(!utils.isString(this.end)) {
				end = '2300-1-1 00:00';
			}
			
			// 将开始日期和结束日期转为 Date 
			let dtStart = utils.formatDate(start).dt;
			let dtEnd = utils.formatDate(end).dt;
			// 判断有效日期结束是否大于有效日期开始，如果不是，则将有效日期结束修改为有效日期开始往后300年
			if (dtEnd <= dtStart) {
				dtEnd = utils.formatDate(start).dt;
				dtEnd.setFullYear(dtStart.getFullYear() + 300);
				dtEnd.setDate(dtEnd.getDate() - 1);
			}
			
			// 更新开始日期和结束日期
			this.dtStart = dtStart;
			this.dtEnd = dtEnd;
		},
		// 初始化时间选择器数据
		initPickerData() {
			let dfYear = this.dtStart.getFullYear();
			let dfMonth = this.dtStart.getMonth() + 1;
			let dfDay = this.dtStart.getDate();

			this.setYearData();
			this.setMonthData();
			this.setDayData(dfYear, dfMonth);

			if(this.showTime) {
				let dfHour = this.dtStart.getHours();
				let dfMinute = this.dtStart.getMinutes();
				this.setHourData();
				this.setMinuteData();
			}
			this.$nextTick(() => {
				this.setDefaultValue()
			})
		},
		// 设置初始值
		setDefaultValue() {
			let yearIndex, monthIndex, dayIndex, hourIndex, minuteIndex
			let dtDefault
			if(this.defaultValue) {
				dtDefault = utils.formatDate(this.defaultValue).dt;
			} else {
				dtDefault = new Date();
			}
			
      // 初始日期的月份

      let dfYear = this.dtStart.getFullYear();
			let dfMonth = this.dtStart.getMonth() + 1;

			let year = dtDefault.getFullYear()
			let month = dtDefault.getMonth() + 1
			let day = dtDefault.getDate()
			
			// 年份、月份不一样，重新设置天数数据
			if(dfYear != year || dfMonth != month) {
				this.setDayData(year, month)
			}
      
			yearIndex = this.years.findIndex(item => item.number == year)
			monthIndex = this.months.findIndex(item => item.number == month)
      dayIndex = this.days.findIndex(item => item.number == day)
      
			if(this.showTime) {
				let hour = dtDefault.getHours()
				let minute = dtDefault.getMinutes()
        
				hourIndex = this.hours.findIndex(item => item.number == hour)
				minuteIndex = this.minutes.findIndex(item => item.number == minute)
			}
			this.$nextTick(() => {
				this.value = [yearIndex, monthIndex, dayIndex, hourIndex || 0, minuteIndex || 0]
			})
		},
		// 确认
    confirm() {
			let year, month, day, hour, minute;
			if(!this.dateStr) {
				let [yearIndex, monthIndex, dayIndex, hourIndex, minuteIndex] = this.value
				year = this.years[yearIndex].number
				month = this.months[monthIndex].number
				day = this.days[dayIndex].text
				
				let dtStr = ''
				if(this.showYear) {
					dtStr = `${year}`
				}
				if(this.showMonth) {
					dtStr = `${year}-${month}`
				}
				if(this.showTime) {
					hour = this.hours[hourIndex].text
					minute = this.minutes[minuteIndex].text
					dtStr = `${year}-${month}-${day}`
				}
				
				// let dtStr = this.showTime ? `${year}-${month}-${day} ${hour}:${minute}` : `${year}-${month}-${day}`
				console.log('dtStr', dtStr);
				this.$emit('confirm', this.setDateStr(dtStr));
			} else {
				this.$emit('confirm', this.dateStr);
			}
    },
		/**
		 * cancel
		 */
		cancel() {
			this.$emit('cancel')
		},
		/**
		 * change选择
		 */
		change(event) {
      let year, month, day, hour, minute;
			let [yearIndex, monthIndex, dayIndex, hourIndex, minuteIndex] = event.detail.value
      year = this.years[yearIndex].number
			this.setMonthData(year)
      month = this.months[this.months.length>monthIndex ? monthIndex : this.months.length-1].number
      this.setDayData(year, month)
      day = this.days[dayIndex] && this.days[dayIndex].number
      
			this.lastYearIndex = yearIndex
			this.lastMonthIndex = monthIndex

			if(this.showTime) {
        this.setHourData(year, month, day)
        hour = this.hours[hourIndex].number
        this.setMinuteData(year, month, day, hour)
      	minute = this.minutes[minuteIndex].number
			}

			let dtStr = `${year}-${month}-${day} ${hour}:${minute}`
			// 回调传出结果
      this.$emit('change', this.setDateStr(dtStr));
		},

		/**
		 * 设置显示的值
		 * @param {Date|String} date 日期字符串或日期对象
		 */
		setDateStr(date) {
			let dt = utils.formatDate(date);
			if(this.showTime) {
				this.dateStr = `${dt.YYYY}-${dt.MM}-${dt.DD} ${dt.hh}:${dt.mm}`
			} else {
				this.dateStr = `${dt.YYYY}-${dt.MM}-${dt.DD}`
			}
			return this.dateStr
		},
		
		/**
		 * 设置年数据
		 */ 
		setYearData() {
			// 有效日期
			let yearStart = this.dtStart.getFullYear();
			let yearEnd = this.dtEnd.getFullYear();
			// 年
			this.years = [];
			for (let year = yearStart; year <= yearEnd; year++) {
				let item = {
					number: year,
					text: `${year}年`,
				};
				this.years.push(item);
			}
		},
		
		/**
		 * 设置月数据
		 * @param {Number} year 年 
		 */ 
		setMonthData(year) {
			let yearStart = this.dtStart.getFullYear();
			let monthStart = this.dtStart.getMonth() + 1;
			let yearEnd = this.dtEnd.getFullYear();
			let monthEnd = this.dtEnd.getMonth() + 1;
			let chooseYear = year || parseInt(utils.getCurrentTime().slice(0,4))

      year = year || yearStart
			// 月
			if(year != yearStart) {
				monthStart = 1
			}

			this.months = [];
			if(chooseYear>=yearEnd){
				for (let month = monthStart; month <= monthEnd; month++) {
					let item = {
						number: month,
						text: `${month >= 10 ? month : '0' + month}月`,
					}
					this.months.push(item);
				}
			}else{
				for (let month = monthStart; month <= 12; month++) {
					let item = {
						number: month,
						text: `${month >= 10 ? month : '0' + month}月`,
					}
					this.months.push(item);
				}
			}
		},
		
		/**
		 * 设置日数据
		 * @param {Number} year 年 
		 * @param {Number} month 月 
		 */ 
		setDayData(year, month) {
			// 有效日期
			let yearStart = this.dtStart.getFullYear();
			let monthStart = this.dtStart.getMonth() + 1;
			let dayStart = this.dtStart.getDate();
			let yearEnd = this.dtEnd.getFullYear();
			let monthEnd = this.dtEnd.getMonth() + 1;
			let dayEnd = this.dtEnd.getDate();
			let chooseYear = year || parseInt(utils.getCurrentTime().slice(0,4))

			year = year || yearStart;
			month = month || monthStart;

			// 获取当前年月的有效天数
			let now = new Date(year, month, 0);
      let dayCount = now.getDate();

			if(year != yearStart || month != monthStart) {
				dayStart = 1
			}

			// 日
			this.days = [];
			if(chooseYear>=yearEnd&&month>=monthEnd){
				for (let day = dayStart; day <= dayEnd; day++) {
					let item = {
						number: day,
						text: `${day >= 10 ? day : '0' + day}`,
					};
					this.days.push(item);
				}
			}else{
				for (let day = dayStart; day <= dayCount; day++) {
					let item = {
						number: day,
						text: `${day >= 10 ? day : '0' + day}`,
					};
					this.days.push(item);
				}
			}
		},
		
		/**
		 * 设置时数据
		 * @param {Number} year 年 
		 * @param {Number} month 月 
		 * @param {Number} day 日 
		 */ 
		setHourData(year, month, day) {
			let yearStart = this.dtStart.getFullYear();
			let monthStart = this.dtStart.getMonth() + 1;
			let dayStart = this.dtStart.getDate();
      let hourStart = this.dtStart.getHours();

      year = year || yearStart;
      month = month || monthStart;
      day = day || dayStart

			if(year != yearStart || month != monthStart || day != dayStart) {
        hourStart = 0;
			}
			// 时
			this.hours = [];
			for (let hour = hourStart; hour <= 23; hour++) {
				let item = {
					number: hour,
					text: `${hour >= 10 ? hour : '0' + hour}`,
				};
				this.hours.push(item);
      }
		},
		
		/**
		 * 设置分数据
		 * @param {Number} year 年 
		 * @param {Number} month 月 
		 * @param {Number} day 日
		 * @param {Number} hour 时
		 */ 
		setMinuteData(year, month, day, hour) {
      // 有效日期
      let yearStart = this.dtStart.getFullYear();
			let monthStart = this.dtStart.getMonth() + 1;
			let dayStart = this.dtStart.getDate();
      let hourStart = this.dtStart.getHours();

      let minuteStart = this.dtStart.getMinutes();
      
			year = year || yearStart;
      month = month || monthStart;
      day = day || dayStart
      hour = hour || hourStart

      if(year != yearStart || month != monthStart || day != dayStart || hour != hourStart) {
        minuteStart = 0;
      }
			// 分
			this.minutes = [];
			for(let minute = minuteStart; minute <= 59; minute++) {
				let item = {
					number: minute,
					text: `${minute >= 10 ? minute : '0' + minute}`,
				}
				this.minutes.push(item);
      }
		}
	}
}
</script>

<style lang="scss" scoped>
.primary-button {
  font-size: 32rpx;
	width: 210rpx;
	height: 71rpx;
	line-height: 71rpx;
	border-radius: 13rpx;
  color: #fff;
  background: #E74954;
	margin-bottom: 50rpx;
}

.cancel-button {
	font-size: 32rpx;
	width: 210rpx;
	height: 71rpx;
	line-height: 71rpx;
	border-radius: 13rpx;
	color: #E74954;
	background: #fdecee;
	margin-bottom: 50rpx;
}

.content {
	text-align: right;
}
.date-time {
  padding: 40rpx 100rpx;
}
.placeholder {
  color: #a6a7a8;
  font-size: 28rpx;
}
.picker-view {
  height: 360rpx;
  width: 100%;
  box-sizing: border-box;
  &-cloumn {
    .item {
      font-size: 36rpx;
      font-weight: 500;
      text-align: center;
    }
    &.time {
      margin-left: 120rpx;
    }
  }
}
.form-button {
	width: 100%;
  margin-bottom: 20rpx;
  &.blue {
    background: linear-gradient(-68deg, #3293F8, #4D81F9); 
  }
}
</style>
